/****************************************
 * Copyright (c) 2015 NiuWa.
 * All rights reserved.
 * Created on 2015年4月23日
 * 
 * Contributors:
 * 	   bwz - initial implementation
 ****************************************/
package com.niuwa.p2p.core.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

import com.niuwa.p2p.core.utils.DictConstant.TimeUit;

import static com.niuwa.p2p.core.constant.Constants.*;


/**
 * @title 所有交易相关，依赖的计算公式都放在此类中
 *
 * @author bwz
 * @version 1.0
 * @created 2015年4月23日
 */
public class CalculateBusiUtils {
	
	/**
	 * 借款服务费
	 * @author Percy.Lo
	 * @param loanAmount 借款金额
	 * @param platformRate 平台费率，如4%用4表示，如果不收服务费则为0
	 * @param lowPlatformFee 最低平台服务费，如果不收服务费或没有最低的限制则为0
	 * @return max(借款金额*平台费率/100,最低平台服务费),保留两位小数
	 */
	public static BigDecimal LoanServiceCharge(BigDecimal loanAmount,BigDecimal platformRate,BigDecimal lowPlatformFee){
		if(loanAmount==null)
			throw new RuntimeException("计算平台服务费时异常，借款金额loanAmount为NULL！");
		if(platformRate==null)
			throw new RuntimeException("计算平台服务费时异常，平台费率platformRate为NULL！");
		if(lowPlatformFee==null)
			throw new RuntimeException("计算平台服务费时异常，最低平台服务费lowPlatformFee为NULL！");
		return (loanAmount.multiply(platformRate).divide(BG100,CURRENCY_DB_SCALE,RoundingMode.UP)).max(lowPlatformFee);
	}
	
	/**
	 * 债权转让服务费
	 * @author Percy.Lo 
	 * @param transferAmount 债权本金
	 * @param transferRate 债权转让服务费率
	 * @return 债权本金*债权转让服务费率,保留两位小数
	 */
	public static BigDecimal TransferServiceCharge(BigDecimal transferAmount,BigDecimal transferRate){
		if(transferAmount==null)
			throw new RuntimeException("计算债权转让服务费时异常，债权本金transferAmount为NULL！");
		if(transferRate==null)
			throw new RuntimeException("计算债权转让服务费时异常，债权转让服务费率transferRate为NULL！");
		return transferAmount.multiply(transferRate).divide(BG100,CURRENCY_DB_SCALE,RoundingMode.UP);
	}
	
	/**
	 * 计算平台补贴
	 * @author Percy.Lo 
	 * @param investAmount 投资金额
	 * @param actualAmount 实际收益
	 * @param termType 投资周期类型
	 * @param investTerm 投资周期
	 * @param yearRate 预期年化收益率
	 * @param addYield 附加收益率(平台奖励)
	 * @return max(方案应计约定收益-方案到期实际收益,0)
	 */
	public static BigDecimal platformSubsidies(BigDecimal investAmount,BigDecimal actualAmount,String termType,int investTerm,BigDecimal yearRate,BigDecimal addYield){
		BigDecimal rate=yearRate.add(addYield);
		TimeUit unit=TimeUit.valueOf(termType);
		switch (unit) {
		case M:
			rate=rate.divide(MONTH_OF_YEAR.multiply(BG100),CURRENCY_DB_SCALE,RoundingMode.DOWN);//月收益率
			break;
		case D:
			rate=rate.divide(DAY_OF_YEAR.multiply(BG100),CURRENCY_DB_SCALE,RoundingMode.DOWN);//日收益率
			break;
		default:
			throw new RuntimeException("未知的周期类型！ termType="+termType);
		}
		BigDecimal contractrevenue=investAmount.multiply(new BigDecimal(investTerm)).multiply(rate);//约定收益
		return contractrevenue.subtract(actualAmount).max(BigDecimal.ZERO);//平台补贴
	}
	
	/**
	 * 计算计划类的应计收益
	 * @author bwz
	 * @param userBidMoney 用户投资金额
	 * @param yearRate 计划的年化利率
	 * @param loanTerm 借款期限
	 * @param termType 期限类型
	 * @return
	 */
	public static BigDecimal calPlanIncome(BigDecimal userBidMoney,BigDecimal yearRate,	int loanTerm,String termType){
		BigDecimal income = BigDecimal.ZERO; 
		if(termType.equals(DictConstant.TimeUit.D.getCode())){
			BigDecimal multiplyResult = userBidMoney.multiply(BigDecimal.valueOf(loanTerm)).multiply(yearRate);
			income = multiplyResult.divide(BigDecimal.valueOf(100L)).divide(DAY_OF_YEAR,CURRENCY_DB_SCALE,BigDecimal.ROUND_DOWN);
		}else if(termType.equals(DictConstant.TimeUit.M.getCode())){
			BigDecimal multiplyResult = userBidMoney.multiply(BigDecimal.valueOf(loanTerm)).multiply(yearRate);
			income = multiplyResult.divide(BigDecimal.valueOf(100L)).divide(MONTH_OF_YEAR,CURRENCY_DB_SCALE,BigDecimal.ROUND_DOWN);
		}else{
			//TODO 未知类型，如何处理
		}
		return income;
	}
	
	
	
	public static void main(String[] args) {
		BigDecimal userBidMoney = BigDecimal.valueOf(2000);
		BigDecimal yearRate = BigDecimal.valueOf(7);
		int loanTerm = 13;
		String termType = "D";
		BigDecimal result = calPlanIncome(userBidMoney, yearRate, loanTerm, termType );
		
		System.out.println("计算后结果为：" + result);
		
		TimeUit tmp=TimeUit.valueOf("M");
		System.out.println(tmp.getName()+"=="+(tmp==TimeUit.M));
	}
	
	
}
